package com.lk.oauth2.resource.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;

/**
 * @description: - @EnableResourceServer开启资源服务器，请求服务中的资源，就要带着token过来，找不到token或token无效，访问不了资源；
 *     - @EnableGlobalMethodSecurity 开启方法级别权限控制，配合@Configuration使用
 * @author: Li Kang
 * @create: 2020-09-04 10:03
 */
@Configuration
@EnableResourceServer
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

  private static final Logger logger = LoggerFactory.getLogger(ResourceServerConfig.class);
  private static final String RESOURCE_ID = "product-server";

  @Autowired private TokenStore tokenStore;

  @Override
  public void configure(ResourceServerSecurityConfigurer resources) {
    // 当前资源服务器的资源id，认证服务器会认证客户端有没有访问这个资源的权限，有则可以访问当前服务
    resources
        .resourceId(RESOURCE_ID)
        // .tokenServices(tokenService())
        .tokenStore(tokenStore);
  }

  /// 远程认证服务器进行校验，通过查数据库查询用户权限
  ///  public ResourceServerTokenServices tokenService() {
  //    // 远程认证服务器进行校验 token是否有效
  //    RemoteTokenServices service = new RemoteTokenServices();
  //    // 请求认证服务器校验的地址，默认情况 这个地址在认证服务器它是拒绝访问的，要设置放行
  //    service.setCheckTokenEndpointUrl("http://localhost:8090/auth/oauth/check_token");
  //    service.setClientId("lk-pc");
  //    service.setClientSecret("lk-secret");
  //    return service;
  //  }

  /**
   * 配置授权规则
   *
   * @param http
   * @throws Exception
   */
  @Override
  public void configure(HttpSecurity http) throws Exception {
    http.sessionManagement()
        // SpringSecurity不会使用也不会创建HttpSession实例
        .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        .and()
        .authorizeRequests()
        // 1.通过用户权限授权
        //        .antMatchers("/product/list")
        //        .hasAuthority("product")
        // 2.通过oauth2的授权范围：所有请求，都需要有all范围（scope）
        .antMatchers("/**")
        .access("#oauth2.hasScope('all')")
        // 3.等价于2
        .anyRequest()
        .access("#oauth2.hasScope('all')");
  }
}
